package com.ygqh.baby.service.impl;

import com.foxinmy.weixin4j.util.StringUtil;
import com.ygqh.baby.ao.*;
import com.ygqh.baby.constant.Constant;
import com.ygqh.baby.exception.YgException;
import com.ygqh.baby.handler.SaveReturnOrderHandler;
import com.ygqh.baby.mapper.YgReturnOrderMapper;
import com.ygqh.baby.model.*;
import com.ygqh.baby.model.wdt.qyb.WdtQybResult;
import com.ygqh.baby.po.*;
import com.ygqh.baby.po.YgReturnOrderExample.Criteria;
import com.ygqh.baby.service.*;
import com.ygqh.baby.service.pay.app.alipay.AlipayAppApi;
import com.ygqh.baby.service.pay.app.weixin.WxAppPayApi;
import com.ygqh.baby.service.task.YgAsynClient;
import com.ygqh.baby.service.wdtqyb.api.WdtQybApi;
import com.ygqh.baby.service.wdtqyb.api.WdtQybPushOrderByDetailApi;
import com.ygqh.baby.service.wdtqyb.exception.WdtException;
import com.ygqh.baby.service.wechat.YgWeChatService;
import com.ygqh.baby.template.AbstractSplitListTemplate;
import com.ygqh.baby.utils.DateConvertUtils;
import com.ygqh.baby.utils.ReturnSkuInfoComparator;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.Map.Entry;
import java.util.stream.Collectors;

@Service
public class YgReturnOrderServiceImpl implements YgReturnOrderService {
    protected final Logger logger = Logger.getLogger(YgReturnOrderServiceImpl.class);

    @Autowired
    private YgReturnOrderMapper ygReturnOrderMapper;
    @Autowired
    private YgReturnOrderDetailService ygReturnOrderDetailService;
    @Autowired
    private YgOrderService ygOrderService;
    @Autowired
    private YgLogisticsService ygLogisticsService;
    @Autowired
    private YgReturnOrderLogService ygReturnOrderLogService;
    @Autowired
    private WxMpMessageService wxMpMessageService;
    @Autowired
    private YgUserService userService;
    @Autowired
    private YgFrameCodeService ygFrameCodeService;
    @Value("${return.valid.express_price}")
    private Boolean validExpPrice;
    @Autowired
    private YgUserBalanceService userBalanceService;
    @Autowired
    private YgOrderPaymentService ygOrderPaymentService;
    @Autowired
    private WdtQybApi wdtQybApi;
    @Autowired
    private YgAsynClient ygAsynClient;
    @Autowired
    private YgAlipayRefundRecordService ygAlipayRefundRecordService;
    @Autowired
    private WxSmallAuthorityService wxSmallAuthorityService;
    @Autowired
    private YgReturnLogService ygReturnLogService;
    @Autowired
    private YgOrderDetailService ygOrderDetailService;
    @Autowired
    private YgUserMemberService ygUserMemberService;
    @Autowired
    private YgUserBalanceService ygUserBalanceService;
    @Autowired
    private ScheduleJobService scheduleJobService;
    @Autowired
    private YgWeChatService ygWeChatService;
    @Autowired
    private YgSupplierService ygSupplierService;
    @Autowired
    private AlipayAppApi alipayAppApi;
    @Autowired
    private WxAppPayApi wxAppPayApi;
    @Autowired
    private YgPlatformService ygPlatformService;
    @Autowired
    private YgPayService ygPayService;
    @Autowired
    private YgCardCouponDetailService ygCardCouponDetailService;
    @Autowired
    private YgPrepayBookRecordService ygPrepayBookRecordService;
    @Autowired
    private WxSmallMessageService wxSmallMessageService;
    @Autowired
    private SaveReturnOrderHandler saveReturnOrderHandler;
    @Autowired
    private KidsOrderLogisticsService kidsOrderLogisticsService;

    @Value("${trustoner.supplier.id}")
    private Long trustonerSupplierId;

    @Override
    public List<YgReturnOrder> find(Long... orderIds) {
        YgReturnOrderExample example = new YgReturnOrderExample();
        Criteria criteria = example.createCriteria().andStatusEqualTo(DataStatus.Valid.name());
        if (orderIds != null) {
            criteria.andOrderIdIn(Arrays.asList(orderIds));
        }
        return ygReturnOrderMapper.selectByExample(example);
    }

    @Override
    public int findCount() {
        YgReturnOrderExample example = new YgReturnOrderExample();
        example.createCriteria().andStatusEqualTo(DataStatus.Valid.name());
        return ygReturnOrderMapper.countByExample(example);
    }

    @Override
    public YgReturnOrder findById(Long id) {
        return ygReturnOrderMapper.selectByPrimaryKey(id);
    }

    @Override
    public int save(YgReturnOrder ygReturnOrder) {
        return ygReturnOrderMapper.insertSelective(ygReturnOrder);
    }

    @Override
    public int update(YgReturnOrder ygReturnOrder) {
        return ygReturnOrderMapper.updateByPrimaryKeySelective(ygReturnOrder);
    }

    @Override
    public int deleteSoft(Long[] ids) {
        Assert.notEmpty(ids);
        YgReturnOrderExample example = new YgReturnOrderExample();
        example.createCriteria().andIdIn(Arrays.asList(ids));
        YgReturnOrder record = new YgReturnOrder();
        record.setStatus(DataStatus.Delete);

        return ygReturnOrderMapper.updateByExampleSelective(record, example);
    }

    @Override
    public int deleteSoft(Long id) {
        return this.deleteSoft(new Long[]{id});
    }

    @Override
    public int saveOrUpdate(YgReturnOrder ygReturnOrder) {
        int r = 0;
        if (ygReturnOrder.getId() != null) {
            r = this.update(ygReturnOrder);
        } else {
            r = this.save(ygReturnOrder);
        }
        return r;
    }

    @Override
    public ResultSet<YgReturnOrder> search(QueryInfo queryInfo, String q, String username, ReturnType returnType, String returnCode, Date startDate, Date
            endDate, Long orderId, ReturnStatus returnStatus, String expressCode, String productName) {
        List<YgReturnOrder> list = ygReturnOrderMapper.selectSuper(queryInfo, q, username, returnType, returnCode, startDate, endDate, orderId, returnStatus,
                expressCode, productName);
        int count = ygReturnOrderMapper.countSuper(q, username, returnType, returnCode, startDate, endDate, orderId, returnStatus, expressCode, productName);
        ResultSet<YgReturnOrder> resultSet = new ResultSet<>(count, list);
        return resultSet;
    }

    /**
     * TODO 待优化
     * 该接口存在一个有待优化问题：
     * 如果查询出的订单列表。 既不能退也不能换。会导致返回数据不足分页查询数据。临界值会导致没有数据返回。
     */
    @Override
    public List<YgOrderModel> findOrderListForReturn(QueryInfo queryInfo, Long userId) {
        return findOrderListForReturn(queryInfo, userId, Constant.YIIGOO_PLATFORM_NO);
    }

    @Override
    public List<YgOrderModel> findOrderListForReturn(QueryInfo queryInfo, Long userId, String platformNo) {
        Date currentDate = new Date();
        Date limitDate = DateConvertUtils.addDay(currentDate, -10);
        List<YgOrderModel> list = ygReturnOrderMapper.selectOrderListForReturn(queryInfo, userId, limitDate, platformNo);
        Iterator<YgOrderModel> iterator = list.iterator();
        while (iterator.hasNext()) {
            YgOrderModel model = iterator.next();
            if (model.getOrderType().equals(OrderType.CardCoupon)) { // 卡券订单，不可退不可换
                iterator.remove();
                continue;
            }
            if (trustonerSupplierId.equals(model.getSupplierId())) {
                iterator.remove();
                continue;
            }
            Map<String, Object> map = this.existenceReturnByOrderId(model.getOrderId());
            model.setChangeAble((Boolean) map.get("changeAble"));
            if (model.getParentId() != null && model.getOrderId().compareTo(model.getParentId()) != 0) { // 被赠送卡券兑换订单，不可退货
                model.setReturnAble(false);
            } else {
                model.setReturnAble((Boolean) map.get("returnAble"));
            }
            if (!model.getChangeAble() && !model.getReturnAble()) {
                iterator.remove();
            }
        }
        return list;
    }

    @Override
    public List<YgReturnOrderModel> findReturnList(QueryInfo queryInfo, Long userId) {
        return findReturnList(queryInfo, userId, Constant.YIIGOO_PLATFORM_NO);
    }

    @Override
    public List<YgReturnOrderModel> findReturnList(QueryInfo queryInfo, Long userId, String platformNo) {
        return ygReturnOrderMapper.selectReturnList(queryInfo, userId, platformNo);
    }

    @Override
    public Message sendOutGoods(String returnCode, String expressCompany, String logisticsCode, String expressCode, Long send_count, String createBy) {
        YgLogistics logistics = new YgLogistics();
        logistics.setOrderId(returnCode);
        logistics.setSendTime(new Date());
        logistics.setLogisticsCode(logisticsCode);
        logistics.setExpressCompany(expressCompany);
        logistics.setExpressCode(expressCode);
        logistics.setCreateTime(new Date());
        ygLogisticsService.save(logistics);
        YgReturnOrder order = this.findDetailByReCode(returnCode);
        order.setSendCount(order.getSendCount() + send_count);
        order.setSendTime(logistics.getSendTime());
        order.setUpdateBy(createBy);
        order.setUpdateTime(order.getSendTime());
        order.setReturnStatus(ReturnStatus.WaitingSign);
        this.update(order);

        YgReturnOrderLog log = ygReturnOrderLogService.findByReturnCode(returnCode, ReturnStatus.WaitingSign);
        if (log == null)
            ygReturnOrderLogService.addReturnOrderLog(returnCode, "您的换货已发出。物流信息：" + expressCompany + expressCode, ReturnStatus.WaitingSign, createBy, null);
        String productName = order.getReturnOrderDetails().get(0).getProductName();
        // YgProduct product = productService.findById(pid);
        wxMpMessageService.sendGoods4Change(expressCompany, expressCode, productName + "等 " + send_count + "件", order.getOrderId(), order.getUserId());

        kidsOrderLogisticsService.addBatchByYgLogistics(Collections.singletonList(logistics));
        return Message.success("");
    }

    @Override
    public Map<String, Object> existenceReturnByOrderId(Long orderId) {
        Boolean returnAble = true;
        Boolean changeAble = true;
        List<YgReturnOrder> list = this.findRetrunByOrderId(orderId);
        for (YgReturnOrder returnOrder : list) {
            // 非驳回及取消状态
            if (!returnOrder.getReturnStatus().equals(ReturnStatus.Cancel) && !returnOrder.getReturnStatus().equals(ReturnStatus.Reject)) {
                YgOrder ygOrder = ygOrderService.findOrderDetailByOrderId(returnOrder.getOrderId());
                int types = getReturnSkuTypes(returnOrder.getReturnOrderDetails());
                // 存在退货
                if (returnOrder.getReturnType().equals(ReturnType.Return)) {
                    returnAble = false;
                    if (types == ygOrder.getOrderDetail().size()) {
                        changeAble = false;
                    }
                }
                // 存在换货
                if (returnOrder.getReturnType().equals(ReturnType.Change)) {
                    changeAble = false;
                    if (types == ygOrder.getOrderDetail().size()) {
                        returnAble = false;
                    }
                }
            }
        }
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("returnAble", returnAble);
        map.put("changeAble", changeAble);
        return map;

    }

    // 获取退换货原sku种类
    private int getReturnSkuTypes(List<YgReturnOrderDetail> returnOrderDetails) {
        List<Long> sourceSkuIds = new ArrayList<Long>();
        for (YgReturnOrderDetail detail : returnOrderDetails) {
            if (!sourceSkuIds.contains(detail.getSourceSkuId())) {
                sourceSkuIds.add(detail.getSourceSkuId());
            }
        }
        return sourceSkuIds.size();
    }

    @Override
    public List<YgReturnOrder> findRetrunByOrderId(Long orderId) {
        YgReturnOrderExample example = new YgReturnOrderExample();
        example.createCriteria().andStatusEqualTo(DataStatus.Valid.name()).andOrderIdEqualTo(orderId);

        List<YgReturnOrder> list = ygReturnOrderMapper.selectByExample(example);
        for (YgReturnOrder order : list) {
            List<YgReturnOrderDetail> details = ygReturnOrderDetailService.findByReturnCode(order.getReturnCode());
            order.setReturnOrderDetails(details);
        }
        return list;
    }

    @Override
    public YgOrderInfoModel findOrderInfo4Retrun(Long orderId, long userId) {
        return this.findOrderInfo4Retrun(orderId, userId, DataStatus.Valid);
    }

    @Override
    public YgOrderInfoModel findOrderInfo4Retrun(Long orderId, Long userId, DataStatus status) {
        YgOrderInfoModel orderInfo = ygReturnOrderMapper.selectOrderInfo(orderId, userId, status == null ? DataStatus.Valid.name() : status.name());
        return orderInfo;
    }

    @Override
    public Message createExchangeOrder(YgExchangeOrder exchangeOrder, Long userId) throws Exception {
        // 检测是否重复提交
        List<Long> sourceSkuIds = exchangeOrder.getExchangeDetail().stream().map(d -> d.getSourceSkuId()).collect(Collectors.toList());
        Message checkReturn = this.checkReturn(exchangeOrder.getOrderId(), sourceSkuIds, ReturnType.Change);
        if (checkReturn.getType().equals(Message.Type.error)) {
            return checkReturn;
        }

        YgOrder order = ygOrderService.findOrderDetailByOrderId(exchangeOrder.getOrderId());
        Long frameCode = ygFrameCodeService.getFrameCode(CodeType.ReOrder, new Date());
        String returnCode = "H" + frameCode;

        try {

            if (exchangeOrder.getExchangeDetail() == null) return Message.error("执行失败");

            // 检测可换数量
            for (YgExchangeOrderDetail e : exchangeOrder.getExchangeDetail()) {
                for (YgOrderDetail o : order.getOrderDetail()) {
                    if (o.getSkuId().equals(e.getSourceSkuId())) {
                        if (e.getAmount() > o.getQuantity()) {
                            return Message.error("换货的商品数量不能大于原商品数量");
                        }
                        e.setSupplierId(o.getSupplierId());
                        e.setProductName(o.getProductName());
                        e.setShortName(o.getShortName());
                    }
                }
            }
            YgReturnOrder returnOrder = new YgReturnOrder();
            returnOrder.setUserId(userId);
            returnOrder.setReturnCode(returnCode);
            returnOrder.setSupplierId(order.getSupplierId());
            returnOrder.setOrderId(exchangeOrder.getOrderId());
            returnOrder.setReturnType(ReturnType.Change);
            returnOrder.setReturnStatus(ReturnStatus.WaitingCheck);
            returnOrder.setReturnReasonType(exchangeOrder.getReturnReasonType());
            returnOrder.setReturnReason(exchangeOrder.getReturnReason());
            returnOrder.setReturnImgPath(exchangeOrder.getReturnImgPath());
            returnOrder.setCreateTime(new Date());
            exchangeOrder.getExchangeDetail().forEach(e -> {
                e.setReturnCode(returnCode);
                if (ReturnReasonType.ReturnDifference.equals(exchangeOrder.getReturnReasonType())) {
                    // 退差价不记录商品数量
                    e.setAmount(0L);
                }
            });

            ygReturnOrderDetailService.saveExchangeOrderDetailBatch(exchangeOrder.getExchangeDetail());
            this.save(returnOrder);
            ygReturnOrderLogService.addReturnOrderLog(returnCode, "您的申请已提交，等待审核", ReturnStatus.WaitingCheck, userId, null);
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }
        return Message.success(returnCode);
    }

    @Override
    public Message cancelReturnOrder(Long id, Long userId) {
        YgReturnOrder returnOrder = this.findDetailById(id);
        if (!userId.equals(returnOrder.getUserId())) return Message.error("只允许本人操作");

        if (returnOrder.getReturnStatus().equals(ReturnStatus.Cancel)) return Message.error("");

        returnOrder.setReturnStatus(ReturnStatus.Cancel);
        this.update(returnOrder);

        List<Long> list = returnOrder.getReturnOrderDetails().stream().map(d -> d.getSourceSkuId()).collect(Collectors.toList());
        ygOrderDetailService.updateRefundStatusByReturn(returnOrder.getOrderId(), RefundStatus.NoRefund, list);

        YgUser user = userService.findById(userId);
        ygReturnOrderLogService.addReturnOrderLog(returnOrder.getReturnCode(), "您的申请已由【" + user.getUserName() + "】取消", ReturnStatus.Cancel, userId, null);
        return Message.success("");
    }

    @Override
    public YgReturnOrder findDetailById(Long id) {
        return ygReturnOrderMapper.findDetailById(id);
    }

    @Override
    public Message updateLogistics(YgReturnOrderLogisticsModel orderLogisticsModel, Long userId) {
        YgReturnOrder returnOrder = this.findByReturnCode(orderLogisticsModel.getReturnCode());
        if (returnOrder == null) return Message.error("退换货单号不存在");
        if (returnOrder.getReturnStatus().equals(ReturnStatus.WaitingInStock)) return Message.success("");
        returnOrder.setTelPhone(orderLogisticsModel.getTelPhone());
        returnOrder.setProvinceName(orderLogisticsModel.getProvinceName());
        returnOrder.setCityName(orderLogisticsModel.getCityName());
        returnOrder.setAreaName(orderLogisticsModel.getAreaName());
        returnOrder.setAddress(orderLogisticsModel.getAddress());
        returnOrder.setUserExpressCompany(orderLogisticsModel.getUserExpressCompany());
        returnOrder.setUserExpressCode(orderLogisticsModel.getUserExpressCode());
        returnOrder.setReceiver(orderLogisticsModel.getReceiver());
        returnOrder.setReturnStatus(ReturnStatus.WaitingInStock);
        this.update(returnOrder);
        ygReturnOrderLogService.addReturnOrderLog(returnOrder.getReturnCode(), "您的退货已寄回，等待入库。物流信息：" + returnOrder.getUserExpressCompany() + returnOrder
                .getUserExpressCode(), ReturnStatus.WaitingInStock, userId, null);
        return Message.success("");
    }

    @Override
    public YgReturnOrder findReturnOrderDetail(Long id) {
        return ygReturnOrderMapper.findReturnOrderDetail(id);
    }

    @Override
    public YgReturnOrder findByReturnCode(String returnCode) {
        YgReturnOrderExample example = new YgReturnOrderExample();
        example.createCriteria().andStatusEqualTo(DataStatus.Valid.name()).andReturnCodeEqualTo(returnCode);
        List<YgReturnOrder> list = ygReturnOrderMapper.selectByExample(example);
        if (list.isEmpty()) return null;
        return list.get(0);
    }

    @Override
    public YgReturnOrder findDetailByReCode(String returnCode) {
        YgReturnOrderExample example = new YgReturnOrderExample();
        example.createCriteria().andStatusEqualTo(DataStatus.Valid.name()).andReturnCodeEqualTo(returnCode);
        List<YgReturnOrder> list = ygReturnOrderMapper.selectByExample(example);
        if (list != null && list.size() > 0) {
            List<YgReturnOrderDetail> details = ygReturnOrderDetailService.findByReturnCode(returnCode);
            YgReturnOrder returnOrder = list.get(0);
            returnOrder.setReturnOrderDetails(details);
            return returnOrder;
        }
        return null;
    }

    @Override
    public Message getReturnPrice(YgReturnInfoModel returnInfo) {
        BigDecimal returnPrice = new BigDecimal("0");
        YgOrder ygOrder = ygOrderService.findOrderDetailByOrderId(returnInfo.getOrderId());
        Boolean isAllReturn = true;

        // 订单金额=商品金额-N元任选优惠-新客价优惠-拼团优惠金额
        BigDecimal orderPrice = ygOrder.getProductPrice().subtract(ygOrder.getPackDisPrice()).subtract(ygOrder.getNewCustomDisPrice()).subtract(ygOrder
                .getGroupDisPrice()).subtract(ygOrder.getBmdisPrice());

        BigDecimal specialPrice = new BigDecimal(0);

        List<YgOrderDetail> orderDetail = orderDetailGroupByPack(ygOrder.getOrderDetail());

        // 订单中商品总数量
        Long totalCount = 0l;
        // 总退货数量
        Long totalReturnCount = 0l;
        Map<String, List<ReturnSkuInfo>> subDetailMap = new LinkedHashMap<String, List<ReturnSkuInfo>>();
        List<String> keys = new ArrayList<String>();
        for (YgOrderDetail detail : orderDetail) {
            totalCount = totalCount + detail.getQuantity();
            if (detail.getPromotionType().equals(PromotionType.IsSpecial)) {
                // 如果是新客
                if (StringUtil.isNotBlank(detail.getRemark())) {
                    BigDecimal remarkPrice = null;
                    try {
                        remarkPrice = new BigDecimal(detail.getRemark());
                    } catch (Exception e) {
                    }
                    if (remarkPrice == null) {
                        // TODO 暂时策略
                        return Message.error("退货异常，请联系人工客服处理", null);
                    }
                    specialPrice = specialPrice.add(detail.getSalePrice().multiply(new BigDecimal(detail.getQuantity() - 1))).add(remarkPrice);
                } else {
                    specialPrice = specialPrice.add(detail.getSalePrice().multiply(new BigDecimal(detail.getQuantity())));
                }
            }
            /*
             * if (detail.getRemark() == null &&
             * !detail.getPromotionType().equals(PromotionType.Ordinary)) {
             * continue; }
             */
            // 对自选礼包进行分组
            Iterator<ReturnSkuInfo> iterator = returnInfo.getSkuInfos().iterator();
            while (iterator.hasNext()) {
                ReturnSkuInfo next = iterator.next();

                if (next.getSkuId().intValue() == detail.getSkuId()) {
                    totalReturnCount = totalReturnCount + next.getQuantity();
                    next.setPrice(detail.getSalePrice());
                    List<ReturnSkuInfo> subDetails = null;
                    if (detail.getRemark() != null) {
                        String remark = detail.getRemark();
                        String[] split = remark.split(",");
                        if (split.length >= 3) {

                            next.setRemark(remark);
                            next.setBuyCount(detail.getQuantity());
                            subDetails = subDetailMap.get(split[2]);
                            if (subDetails == null) {
                                subDetails = new ArrayList<ReturnSkuInfo>();
                                subDetailMap.put(split[2], subDetails);
                                keys.add(split[2]);
                            }
                            subDetails.add(next);
                        }
                    }
                    // iterator.remove();
                }

            }
        }
        if (totalCount.intValue() > totalReturnCount.intValue()) {
            isAllReturn = false;
        }
        // 处理自选包退款
        BigDecimal packReturnPrice = new BigDecimal(0);
        for (String key : keys) {
            List<ReturnSkuInfo> list = subDetailMap.get(key);
            // 按金额从大到小排序
            ReturnSkuInfoComparator comparator = new ReturnSkuInfoComparator();
            Collections.sort(list, comparator);
            Long buyCount = 0l;
            for (YgOrderDetail detail : ygOrder.getOrderDetail()) {
                if (detail.getRemark() != null) {
                    String[] split = detail.getRemark().split(",");
                    if (split.length >= 3) {

                        if (key.equals(split[2])) {
                            buyCount = buyCount + detail.getQuantity();
                        }
                    }
                }
            }
            // 该自选包退货数量
            Long returnCount = 0l;
            for (ReturnSkuInfo info : list) {
                String remark = "";
                String[] split = info.getRemark().split(",");
                // 自选礼包满足活动的数量
                Long packCount = Long.parseLong(split[1]);
                // 按自选礼包分摊的金额
                BigDecimal packPrice = new BigDecimal(split[0]).divide(new BigDecimal(split[1]), 2, BigDecimal.ROUND_HALF_UP);
                // 当前自选礼包累计退货数量
                returnCount = returnCount + info.getQuantity();
                // 按原价分摊优惠金额
                BigDecimal yDisManJianPrice = this.getDisManJianPrice(ygOrder.getManjianPrice(), orderPrice, info.getPrice());
                BigDecimal yDisYouHuiQuanPrce = this.getDisYouHuiQuanPrce(ygOrder.getYouhuijuanPrice(), orderPrice.subtract(specialPrice), info.getPrice());
                // 按自选包分摊优惠金额
                BigDecimal zDisManJianPrice = this.getDisManJianPrice(ygOrder.getManjianPrice(), orderPrice, packPrice);
                BigDecimal zDisYouHuiQuanPrce = this.getDisYouHuiQuanPrce(ygOrder.getYouhuijuanPrice(), orderPrice.subtract(specialPrice), packPrice);

                // 可以按原价分摊的件数
                Long yCount = 0l;
                // 可以按自选包均摊价退货的件数
                Long zCount = 0l;
                // 退完仍然大于自选包数量
                if (buyCount - returnCount >= packCount) {

                    // 如果此商品原价购买数量 大于 退货数量
                    if (info.getBuyCount().intValue() - Integer.parseInt(split[3]) >= info.getQuantity().intValue()) {
                        yCount = info.getQuantity();
                    } else {
                        yCount = info.getQuantity() - (info.getBuyCount() - Long.parseLong(split[3]));
                    }
                    zCount = info.getQuantity() - yCount;
                } else {

                    // 上一次退了多少件
                    Long preCount = returnCount - info.getQuantity();
                    // 还有多少件可退
                    Long returnAbleCount = buyCount - preCount;
                    // 剩下多少件
                    Long leftCount = returnAbleCount - info.getQuantity();

                    // 可退数量<=自选包数量
                    if (returnAbleCount.intValue() <= packCount.intValue()) {
                        // 刚好退完。
                        zCount = info.getQuantity();
                        yCount = 0l;
                    } else if (returnAbleCount.intValue() > packCount.intValue()) {
                        // 可退数量大于自选包数量
                        zCount = packCount - leftCount;
                        yCount = info.getQuantity() - zCount;

                    }
                }
                BigDecimal yPrice = info.getPrice().subtract(yDisManJianPrice).subtract(yDisYouHuiQuanPrce);
                BigDecimal yReturnPrice = yPrice.multiply(new BigDecimal(yCount));

                BigDecimal zPrice = packPrice.subtract(zDisManJianPrice).subtract(zDisYouHuiQuanPrce);
                BigDecimal zReturnPrice = zPrice.multiply(new BigDecimal(zCount));

                packReturnPrice = packReturnPrice.add(yReturnPrice).add(zReturnPrice);

                remark = remark + ";" + yPrice + "," + yCount + ";" + zPrice + "," + zCount;
                info.setPrice(packPrice);
                info.setRemark(remark);
            }
        }

        for (ReturnSkuInfo model : returnInfo.getSkuInfos()) {
            for (YgOrderDetail detail : ygOrder.getOrderDetail()) {
                if (model.getSkuId().intValue() == detail.getSkuId().intValue()) {
                    // 购买数量小于退货数量
                    if (detail.getQuantity().intValue() < model.getQuantity().intValue()) {
                        return Message.error("退货数量不能大于购买数量", model.getSkuId());
                    }
                    if (model.getQuantity().intValue() < detail.getQuantity().intValue()) {
                        isAllReturn = false;
                    }
                    BigDecimal manJianPrice = new BigDecimal(0);
                    BigDecimal newCusMjPrice = new BigDecimal(0);
                    BigDecimal newCusPrice = new BigDecimal(0);
                    BigDecimal yhqPrice = new BigDecimal(0);
                    BigDecimal price = new BigDecimal(0);
                    // 自选礼包商品
                    if (detail.getRemark() != null && detail.getPromotionType().equals(PromotionType.Ordinary)) {
                        continue;
                    } else {

                        // 非自选礼包商品
                        // 如果是特例品，不分摊优惠券，需分摊满减优惠
                        if (detail.getPromotionType().equals(PromotionType.IsSpecial)) {
                            String remark = detail.getRemark();
                            // 新客商品
                            if (StringUtil.isNotBlank(remark)) {
                                // 按原价退
                                if (model.getQuantity().intValue() < detail.getQuantity().intValue()) {
                                    manJianPrice = getDisManJianPrice(ygOrder.getManjianPrice(), orderPrice, detail.getSalePrice());
                                } else {
                                    manJianPrice = getDisManJianPrice(ygOrder.getManjianPrice(), orderPrice, detail.getSalePrice());
                                    newCusMjPrice = getDisManJianPrice(ygOrder.getManjianPrice(), orderPrice, new BigDecimal(detail.getRemark()));
                                    newCusPrice = new BigDecimal(detail.getRemark()).subtract(newCusMjPrice);
                                }
                                price = detail.getSalePrice().subtract(manJianPrice);
                            } else {

                                manJianPrice = getDisManJianPrice(ygOrder.getManjianPrice(), orderPrice, detail.getSalePrice());
                                // 特例品不能使用优惠券，所以应退金额=实际金额-满减优惠金额

                                price = detail.getSalePrice().subtract(manJianPrice);
                                manJianPrice = new BigDecimal(0);
                            }
                        } else {
                            // 存在满减计算满减分摊
                            manJianPrice = getDisManJianPrice(ygOrder.getManjianPrice(), orderPrice, detail.getSalePrice());

                            yhqPrice = getDisYouHuiQuanPrce(ygOrder.getYouhuijuanPrice(), orderPrice.subtract(specialPrice), detail.getSalePrice());
                            price = detail.getSalePrice().subtract(manJianPrice).subtract(yhqPrice);
                        }
                    }
                    if (price.compareTo(BigDecimal.ZERO) < 0) {
                        price = BigDecimal.ZERO;
                    }
                    if (newCusPrice.compareTo(new BigDecimal(0)) > 0) {
                        returnPrice = returnPrice.add(price.multiply(new BigDecimal(model.getQuantity().intValue() - 1)).add(newCusPrice));
                        model.setRemark(price + "," + (model.getQuantity().intValue() - 1) + ";" + newCusPrice + ",1");
                    } else {
                        returnPrice = returnPrice.add(price.multiply(new BigDecimal(model.getQuantity())));
                    }
                    model.setPrice(price);

                }

            }
        }
        BigDecimal expressPrice = new BigDecimal(0);
        returnPrice = packReturnPrice.add(returnPrice);
        // if (validExpPrice) {
        // expressPrice =ygOrder.getExpressPrice();
        // }
        // 全部退货
        returnInfo.setExpressPrice(expressPrice);
        if (isAllReturn) {
            // 已发货的订单需扣除运费
            if (ygOrder.getSendTime() != null) {
                returnInfo.setReturnPrice(ygOrder.getTotalPrice().add(ygOrder.getAccountPrice()).subtract(ygOrder.getExpressPrice()));
            } else {
                // 未发货的订单全额返还
                returnInfo.setReturnPrice(ygOrder.getTotalPrice().add(ygOrder.getAccountPrice()));
            }
        } else {
            returnInfo.setReturnPrice(returnPrice.subtract(expressPrice));
        }
        return Message.success(returnInfo);
    }

    private List<YgOrderDetail> orderDetailGroupByPack(List<YgOrderDetail> orderDetail) {
        Map<String, List<YgOrderDetail>> detailMap = new LinkedHashMap<String, List<YgOrderDetail>>();
        List<String> keys = new ArrayList<String>();
        for (YgOrderDetail detail : orderDetail) {
            List<YgOrderDetail> subDetails = null;
            if (detail.getRemark() != null) {
                String[] split = detail.getRemark().split(",");
                if (split.length >= 3) {

                    String packId = split[2];

                    subDetails = detailMap.get(packId);
                    if (subDetails == null) {
                        subDetails = new ArrayList<YgOrderDetail>();
                        detailMap.put(split[2], subDetails);
                        keys.add(split[2]);
                    }
                    subDetails.add(detail);
                }

                // TODO (暂时策略) 校验明细, 如果明细remark值不能空并且明细商品为特例品，改明细商品为普通商品
                if (PromotionType.IsSpecial.equals(detail.getPromotionType())) {
                    detail.setPromotionType(PromotionType.Ordinary);
                }
            }

        }

        for (String key : keys) {
            List<YgOrderDetail> list = detailMap.get(key);
            Long amount = 0l;
            String[] split = list.get(0).getRemark().split(",");
            long packCount = Long.parseLong(split[1]);
            for (YgOrderDetail detail : detailMap.get(key)) {
                amount = amount + detail.getQuantity();
                if (amount < packCount) {
                    detail.setRemark(detail.getRemark() + "," + detail.getQuantity());
                } else if (amount == packCount) {
                    detail.setRemark(detail.getRemark() + "," + detail.getQuantity());
                    break;
                } else {
                    Long preCount = amount - detail.getQuantity();
                    Long diffCount = packCount - preCount;
                    detail.setRemark(detail.getRemark() + "," + diffCount);
                    break;
                }
            }
        }
        return orderDetail;
    }

    // 获取每个商品优惠券优惠的金额
    private BigDecimal getDisYouHuiQuanPrce(BigDecimal youhuijuanPrice, BigDecimal orderPrice, BigDecimal salePrice) {
        if (youhuijuanPrice.intValue() == 0) {
            return youhuijuanPrice;
        }

        return youhuijuanPrice.multiply(salePrice).divide(orderPrice, 2, BigDecimal.ROUND_HALF_UP);
    }

    // 获取每个商品均摊的满减优惠金额
    private BigDecimal getDisManJianPrice(BigDecimal manjianPrice, BigDecimal orderPrice, BigDecimal salePrice) {
        if (manjianPrice.intValue() == 0) {
            return manjianPrice;
        }
        return manjianPrice.multiply(salePrice).divide(orderPrice, 2, BigDecimal.ROUND_HALF_UP);
    }


    @Override
    public Message saveReturnOrder(YgReturnInfoModel infoModel, ReturnReasonType returnReasonType, String returnReason,
                                   String imgPaths, YgReturnInfoModel returnInfo, Long userId) {
        return saveReturnOrderHandler.saveReturnOrder(infoModel, returnReasonType, returnReason, imgPaths, returnInfo, userId);

    }

    @Override
    public YgReturnOrderInfoModel findReturnOrderInfo(String returnCode, Long userId) {
        YgReturnOrderInfoModel orderInfo = ygReturnOrderMapper.selectReturnOrderInfo(returnCode, userId);

        YgOrderPayment payment = ygOrderPaymentService.findByOrderId(orderInfo.getOrderId().toString());
        if (payment != null) {
            orderInfo.setOrderPayCode(payment.getOrderPayCode());
        }
        // 针对实际未发货发生的换货，需要获取原订单的收货信息
        if (orderInfo.getReturnType().equals(ReturnType.Change) && orderInfo.getReceiver() == null) {
            YgOrder order = ygOrderService.findByOrderId(orderInfo.getOrderId());
            orderInfo.setReceiver(order.getReceiver());
            orderInfo.setTelPhone(order.getTelPhone());
            orderInfo.setProvinceName(order.getProvinceName());
            orderInfo.setCityName(order.getCityName());
            orderInfo.setAreaName(order.getAreaName());
            orderInfo.setAddress(order.getAddress());
        }

        List<YgReturnOrderLog> scheduleList = ygReturnOrderLogService.getReturnScheduleList(returnCode);
        orderInfo.setLastProgress(scheduleList.get(0).getOperation());
        orderInfo.setLastProgressTime(scheduleList.get(0).getCreateTime());
        if (orderInfo.getReturnType().equals(ReturnType.Change)) {
            List<YgReturnOrderDetialModel> sDetailList = new ArrayList<YgReturnOrderDetialModel>();
            List<YgReturnOrderDetialModel> detailList = new ArrayList<YgReturnOrderDetialModel>();

            Map<Long, List<YgReturnOrderDetialModel>> sourceDetailMap = new LinkedHashMap<Long, List<YgReturnOrderDetialModel>>();
            List<Long> sourceKeys = new ArrayList<Long>();

            Map<Long, List<YgReturnOrderDetialModel>> subDetailMap = new LinkedHashMap<Long, List<YgReturnOrderDetialModel>>();
            List<Long> keys = new ArrayList<Long>();
            for (YgReturnOrderDetialModel detail : orderInfo.getSourceDetailList()) {
                // 退货商品
                List<YgReturnOrderDetialModel> sDetails = null;
                sDetails = sourceDetailMap.get(detail.getSourceSkuId());
                if (sDetails == null) {
                    sDetails = new ArrayList<YgReturnOrderDetialModel>();
                    sourceDetailMap.put(detail.getSourceSkuId(), sDetails);
                    sourceKeys.add(detail.getSourceSkuId());
                }
                sDetails.add(detail);
                // 换成商品
                List<YgReturnOrderDetialModel> subDetails = null;
                subDetails = subDetailMap.get(detail.getSkuId());
                if (subDetails == null) {
                    subDetails = new ArrayList<YgReturnOrderDetialModel>();
                    subDetailMap.put(detail.getSkuId(), subDetails);
                    keys.add(detail.getSkuId());
                }
                subDetails.add(detail);
            }
            for (Long key : sourceKeys) {
                List<YgReturnOrderDetialModel> detialModel = sourceDetailMap.get(key);
                Long amount = 0l;
                for (YgReturnOrderDetialModel detail : detialModel) {
                    amount = amount + detail.getAmount();
                }
                YgReturnOrderDetialModel model = (YgReturnOrderDetialModel) detialModel.get(0).clone();
                model.setAmount(amount);
                model.setSkuId(null);
                model.setSkuCode(null);
                model.setSizeName(null);
                sDetailList.add(model);
            }
            for (Long key : keys) {
                List<YgReturnOrderDetialModel> detialModel = subDetailMap.get(key);
                Long amount = 0l;
                for (YgReturnOrderDetialModel detail : detialModel) {
                    amount = amount + detail.getAmount();
                }
                YgReturnOrderDetialModel model = (YgReturnOrderDetialModel) detialModel.get(0).clone();
                model.setAmount(amount);
                model.setSourceSkuId(null);
                model.setSourceSkuCode(null);
                model.setSourceSizeName(null);
                detailList.add(model);
            }

            orderInfo.setSourceDetailList(sDetailList);
            orderInfo.setDetailList(detailList);
        }
        return orderInfo;
    }

    @Override
    public Message auditReturnOrder(String returnCode, String remark, Long userId, String userName,
                                    Boolean passOrReject, OrderStatus orderStatus) {
        ReturnStatus returnStatus;
        YgReturnOrder ygReturnOrder = this.findDetailByReCode(returnCode);
        if (ReturnReasonType.ReturnDifference.equals(ygReturnOrder.getReturnReasonType())) {
            orderStatus = OrderStatus.WaitingSend;
        }
        String logRemark;
        // 通过
        if (passOrReject) {
            // 未发货
            if (orderStatus.equals(OrderStatus.WaitingSend)) {
                if (ygReturnOrder.getReturnType().equals(ReturnType.Change)) {

                    returnStatus = ReturnStatus.WaitingSend;
                    logRemark = "您的换货申请已成功，商品将和原订单一起发出，请耐心等待";
                } else {
                    logRemark = "您的申请已审核通过，工作人员会在3-5个工作日内操作退款。";
                    returnStatus = ReturnStatus.WaitingReturnMoney;
                }
            } else {
                logRemark = "您的申请已审核通过，请于10日内退货并填写退货物流，超时申请将关闭。";
                remark = "1、请在10日内退货并填写物流单号。\n" +
                        "2、请保证商品完好不影响二次销售。\n";
                String withAddress = this.validateOrderToRemark(ygReturnOrder);
                if (StringUtils.isNotBlank(withAddress)) {
                    remark = remark + withAddress;
                }
                returnStatus = ReturnStatus.WaitingReturnGoods;
            }
        } else {
            logRemark = "您的申请未通过审核。原因：" + remark;
            returnStatus = ReturnStatus.Reject;
        }
        // 更新退货单状态
        YgReturnOrder order = new YgReturnOrder();
        order.setReturnCode(returnCode);
        order.setReturnStatus(returnStatus);
        order.setUpdateBy(userName);
        order.setUpdateTime(new Date());
        int i = this.updateReturnStatusByCode(order);
        if (i > 0) {
            // 记录操作日志
            ygReturnOrderLogService.addReturnOrderLog(returnCode, logRemark, returnStatus, userName, remark);
            // 发送审核通知消息
            wxMpMessageService.sendAudit4Return(returnCode, returnStatus, ygReturnOrder.getReturnType(), userId, remark,
                    ygReturnOrder.getOrderId());
            Boolean isSend = !orderStatus.equals(OrderStatus.WaitingSend);
            if (passOrReject) {
                // 退差价单不同步到旺店通
                if (!ReturnReasonType.ReturnDifference.equals(ygReturnOrder.getReturnReasonType())) {
                    ygAsynClient.applyRefundOrder(returnCode, isSend);
                }
                ygReturnLogService.addReturnLog(returnCode, ygReturnOrder.getOrderId(), "审核通过 ,isSend" + isSend, userName, remark);
            }
        }
        return Message.success(i);
    }

    private String validateOrderToRemark(YgReturnOrder ygReturnOrder) {
        YgSupplier supplier = this.findSupplierByReturnOrder(ygReturnOrder);
        StringBuilder sb = new StringBuilder();
        sb.append("退货地址：\n").append(supplier.getReturnAddress())
                .append("，").append(supplier.getReturnReceiver())
                .append("，").append(supplier.getReturnTelPhone()).append("。\n");
        return sb.toString();
    }

    @Override
    public YgSupplier findSupplierByReturnOrder(YgReturnOrder ygReturnOrder) {
        // 明细包含多商家商品，退回壹果；否则退回指定商家
        List<Long> collect = ygReturnOrder.getReturnOrderDetails().stream()
                .map(YgReturnOrderDetail::getSupplierId).distinct().collect(Collectors.toList());
        Long supplierId = collect.size() > 1 ? 1L : collect.get(0);
        return ygSupplierService.findById(supplierId);
    }

    @Override
    public Message cancelReturn(String returnCode, String remark, String userName) {
        // 更新退货单状态
        YgReturnOrder order = this.findDetailByReCode(returnCode);
        order.setReturnCode(returnCode);
        order.setReturnStatus(ReturnStatus.Cancel);
        order.setUpdateBy(userName);
        order.setUpdateTime(new Date());
        int i = this.updateReturnStatusByCode(order);
        if (i > 0) {
            List<Long> skuList = order.getReturnOrderDetails().stream().map(d -> d.getSourceSkuId()).collect(Collectors.toList());
            ygOrderDetailService.updateRefundStatusByReturn(order.getOrderId(), RefundStatus.NoRefund, skuList);
            // 记录操作日志
            ygReturnOrderLogService.addReturnOrderLog(returnCode, remark, ReturnStatus.Cancel, userName, null);
        }

        return Message.success(i);
    }

    @Override
    public Message refund(Long returnOrderId, String serialNumber, String trueName) {
        YgReturnOrder returnOrder = this.findById(returnOrderId);
        returnOrder.setRemark(serialNumber);
        returnOrder.setReturnStatus(ReturnStatus.Complete);
        returnOrder.setRefundPrice(returnOrder.getReturnPrice());
        returnOrder.setRefundAccountPrice(returnOrder.getAccountPrice());
        this.update(returnOrder);

        if (!(returnOrder.getAccountPrice().compareTo(new BigDecimal(0)) == 0)) {
            userBalanceService.backAcountPrice(returnOrder.getUserId(), returnOrder.getAccountPrice());
            userBalanceService.addBalanceDetail(returnOrder.getUserId(), returnOrder.getReturnCode(), returnOrder.getAccountPrice(), BalanceType.Balance,
                    OperationType.ReturnOrder, "退款确认");
        }

        ygReturnOrderLogService.addReturnOrderLog(returnOrder.getReturnCode(), "您的退款已返还，感谢您对我们工作的支持（预计银行到账1~5个工作日）", returnOrder.getReturnStatus(), trueName,
                null);
        return Message.success("");
    }

    private void doRefund(Long returnOrderId, String remark, String handler, BigDecimal refundAccountPrice,
                          BigDecimal refundPrice, String platformNo) {
        YgReturnOrder returnOrder = this.findDetailById(returnOrderId);
        writeBackReturnOrderByRefund(returnOrder.getId(), returnOrder.getReturnReasonType(), remark, handler, refundPrice,
                refundAccountPrice, returnOrder.getReturnOrderDetails());

        if (!ReturnReasonType.ReturnDifference.equals(returnOrder.getReturnReasonType())) {
            // 退差价不改订单明细状态
            this.closeOrderByReturn(returnOrder.getOrderId(), ReturnMode.OnLine, returnOrder.getReturnCode());
        }

        if (refundAccountPrice.compareTo(BigDecimal.ZERO) != 0) {
            userBalanceService.backAcountPrice(returnOrder.getUserId(), refundAccountPrice);
            userBalanceService.addBalanceDetail(returnOrder.getUserId(), returnOrder.getReturnCode(), refundAccountPrice, BalanceType.Balance, OperationType
                    .ReturnOrder, "退款确认", platformNo);
        }
        ygReturnOrderLogService.addReturnOrderLog(returnOrder.getReturnCode(), "您的退款已返还，感谢您对我们工作的支持（预计银行到账1~5个工作日）", ReturnStatus.Complete, handler,
                remark);
        scheduleJobService.addBalanceJobByRof(returnOrder.getOrderId(), handler);

        // 处理卡券订单退款逻辑
        doRefundByCardCouponOrder(returnOrder.getOrderId());
    }

    private void writeBackReturnOrderByRefund(Long returnOrderId, ReturnReasonType returnReasonType, String remark,
                                              String handler, BigDecimal refundPrice, BigDecimal refundAccountPrice,
                                              List<YgReturnOrderDetail> detailList) {
        YgReturnOrder record = new YgReturnOrder();
        record.setId(returnOrderId);
        record.setRemark(remark);
        record.setUpdateBy(handler);
        record.setUpdateTime(new Date());
        record.setRefundPrice(refundPrice);
        record.setRefundAccountPrice(refundAccountPrice);
        record.setReturnStatus(ReturnStatus.Complete);

        if (ReturnReasonType.ReturnDifference.equals(returnReasonType)) {
            // 退差价时回写退款金额及明细
            record.setProductPrice(refundPrice);
            record.setAccountPrice(refundAccountPrice);
            record.setReturnPrice(refundPrice.add(refundAccountPrice));

            BigDecimal lastRefundPrice = refundPrice;
            BigDecimal lastAccountPrice = refundAccountPrice;
            int size = detailList.size();
            for (int i = 0; i < size; i++) {
                YgReturnOrderDetail detail = detailList.get(i);
                BigDecimal price;
                BigDecimal account;
                if (i == size - 1) {
                    price = lastRefundPrice;
                    account = lastAccountPrice;
                } else {
                    price = refundPrice.divide(BigDecimal.valueOf(size), 2, BigDecimal.ROUND_HALF_UP);
                    account = refundAccountPrice.divide(BigDecimal.valueOf(size), 2, BigDecimal.ROUND_HALF_UP);
                    lastRefundPrice = lastRefundPrice.subtract(price);
                    lastAccountPrice = lastAccountPrice.subtract(account);
                }
                detail.setPrice(price);
                detail.setAccountPrice(account);
            }
            ygReturnOrderDetailService.updatePriceBatch(detailList);
        }
        this.update(record);
    }

    @Override
    public Message autoRefund(Long returnOrderId, String remark, String handler, BigDecimal refundPrice, BigDecimal refundAccountPrice) throws YgException {

        YgReturnOrder returnOrder = this.findById(returnOrderId);
        if (returnOrder.getProductPrice().compareTo(refundPrice) < 0) {
            return Message.error("实退现金大于应退");
        }
        if (returnOrder.getAccountPrice().compareTo(refundAccountPrice) < 0) {
            return Message.error("实退成长基金大于应退");
        }
        YgOrder order = ygOrderService.findByOrderId(returnOrder.getOrderId());
        if (ReturnReasonType.ReturnDifference.equals(returnOrder.getReturnReasonType())) {
            // 全额退款时，请选择其它退款理由
            BigDecimal decimal = order.getTotalPrice().add(order.getAccountPrice()).subtract(refundPrice)
                    .subtract(refundAccountPrice);
            if (decimal.compareTo(BigDecimal.ZERO) <= 0) {
                return Message.error("全额退款时，请选择其它理由退款");
            }
        }
        if (refundPrice.compareTo(new BigDecimal("0.00")) == 0) {
            this.doRefund(returnOrderId, remark, handler, refundAccountPrice, refundPrice, order.getPlatformNo());
        } else {

            YgOrderPayment payment = ygOrderPaymentService.findByOrderId(order.getOrderId().toString());

            // applyRefund(null, payment.getPayType(), payment.getAppType(),
            // returnOrder.getReturnCode(), payment.getOrderPayCode(),
            // refundPrice,
            // order.getTotalPrice(), handler1);

            /*
             * 正常情况下定金订单，先退定金
             */
            Message message = ygPrepayBookRecordService.refundRecordByReturnCode(returnOrder.getReturnCode(), refundPrice);
            if (!Message.isSuccess(message)) {
                return message;
            }
            BigDecimal bookPrice = (BigDecimal) message.getExtra();
            // 减去定金
            BigDecimal mainRefundPrice = refundPrice.subtract(bookPrice);
            if (mainRefundPrice.compareTo(BigDecimal.ZERO) > 0) {
                this.applyRefundNew(payment.getPlatformNo(), payment.getPayType(), payment.getAppType(), returnOrder.getReturnCode(), payment.getOrderPayCode
                        (), mainRefundPrice, payment.getPaidPrice(), handler);
            }
            this.doRefund(returnOrderId, remark, handler, refundAccountPrice, refundPrice, order.getPlatformNo());

            String returnReason = returnOrder.getReturnReasonType().getTitle();
            if (StringUtils.isNotBlank(returnOrder.getReturnReason())) {
                returnReason = returnReason + "，" + returnOrder.getReturnReason();
            }
            wxSmallMessageService.sendReturnMoneyMsg(returnOrder.getReturnCode(), refundPrice, returnReason,
                    order.getUserId(), order.getPlatformNo(), payment.getPrepayId());
        }
        pushWdtByRefundMonery(returnOrder.getReturnCode(), returnOrder.getOrderId());
        return Message.success("");

    }

    @Override
    public void applyRefundNew(String platformNo, PayType payType, AppType appType, String returnCode, String orderPayCode, BigDecimal refundPrice,
                               BigDecimal totalPrice, String handler) {

        if (payType.equals(PayType.WeChat)) {
            YgPlatform platform = ygPlatformService.findByPlatformNo(platformNo);
            ygPayService.refund(platform, appType, payType, returnCode, orderPayCode, refundPrice, totalPrice);
        } else if ((appType.equals(AppType.Android) || appType.equals(AppType.Ios)) && payType.equals(PayType.Alipay)) {
            // app支付宝退款
            alipayAppApi.alipayTradeRefund(appType, orderPayCode, returnCode, refundPrice, "订单退货", handler);

        } else {
            throw new YgException("发起退款异常。");
        }

    }

    private void applyRefund(String platformNo, PayType payType, AppType appType, String returnCode, String orderPayCode, BigDecimal refundPrice, BigDecimal
            totalPrice, String handler) {
        if (payType.equals(PayType.WeChat)) {
            if (appType.equals(AppType.Small)) {
                YgPlatform platform = ygPlatformService.findByPlatformNo(platformNo);
                if (platform != null) {
                    ygPayService.refund(platform, appType, payType, returnCode, orderPayCode, refundPrice, totalPrice);
                } else {
                    // 小程序微信支付
                    wxSmallAuthorityService.refund(returnCode, refundPrice, totalPrice, orderPayCode);
                }
            } else if (appType.equals(AppType.WeChat)) {
                // m站 微信支付
                ygWeChatService.refund(returnCode, refundPrice, totalPrice, orderPayCode);

            } else if (appType.equals(AppType.Android) || appType.equals(AppType.Ios)) {

                // app微信
                wxAppPayApi.refund(appType, returnCode, refundPrice, totalPrice, orderPayCode);
            }
        } else if (payType.equals(PayType.Alipay) && (appType.equals(AppType.Android) || appType.equals(AppType.Ios))) {
            // app支付宝退款
            alipayAppApi.alipayTradeRefund(appType, orderPayCode, returnCode, refundPrice, "订单退货", handler);

        } else {
            throw new YgException("发起退款异常。");
        }

    }

    @Override
    public Message saveStockInOrder(List<YgReturnOrderDetail> returnOrderDetail, String trueName) {

        String operation = "您的退货已入库，工作人员会在3-5个工作日内操作换货";
        ReturnStatus returnStatus = ReturnStatus.WaitingSend;

        YgReturnOrder returnOrder = this.findDetailByReCode(returnOrderDetail.get(0).getReturnCode());
        if (returnOrder.getReturnType().equals(ReturnType.Return)) {
            operation = "您的退货已入库，工作人员会在3-5个工作日内操作退款";
            returnStatus = ReturnStatus.WaitingReturnMoney;
        }
        returnOrder.setReturnStatus(returnStatus);
        String addr = returnOrder.getReceiver() + returnOrder.getProvinceName() + returnOrder.getCityName() + returnOrder.getAreaName() + returnOrder
                .getAddress();
        if (StringUtil.isBlank(addr)) {
            YgOrder order = ygOrderService.findByOrderId(returnOrder.getOrderId());
            returnOrder.setReceiver(order.getReceiver());
            returnOrder.setProvinceName(order.getProvinceName());
            returnOrder.setCityName(order.getCityName());
            returnOrder.setAreaName(order.getAreaName());
            returnOrder.setAddress(order.getAddress());
        }

        int i = this.updateReturnStatusByCode(returnOrder);
        if (i > 0) {
            returnOrderDetail.forEach(e -> {
                YgReturnOrderDetail detail = ygReturnOrderDetailService.findByReturnCodeWithSkuId(e.getReturnCode(), e.getSourceSkuId());
                detail.setQuestionDesc(e.getQuestionDesc());
                detail.setAmount(e.getAmount());
                ygReturnOrderDetailService.update(detail);
            });
            ygReturnOrderLogService.addReturnOrderLog(returnOrder.getReturnCode(), operation, returnStatus, trueName, null);

            // 第一单售后退换货，返10成长基金
            freightSubsidyForVip(returnOrder.getUserId(), returnOrder.getReturnCode(), returnOrder.getOrderId());

            // 标记退款成功
            List<Long> skuList = returnOrderDetail.stream().map(d -> d.getSourceSkuId()).collect(Collectors.toList());
            ygOrderDetailService.updateRefundStatusByReturn(returnOrder.getOrderId(), RefundStatus.RefundSuccess, skuList);
            try {
                WdtQybResult result = wdtQybApi.pushChangeOrderAfter(returnOrder);
                // result = wdtService.createChangeOrder(returnOrder);
                if (result.getCode() == 0) {
                    returnOrder.setWdtOrderCode("QYB" + returnOrder.getReturnCode());
                }
            } catch (WdtException e1) {
                logger.error("推送换货单失败；" + e1.getMessage());
                e1.printStackTrace();
            }
        }
        return Message.success("");
    }

    private void freightSubsidyForVip(Long userId, String returnCode, Long orderId) {
        Boolean vip = ygUserMemberService.isVip(userId);
        if (vip) {
            Boolean isFirst = this.isFirstReturnInStockByOrder(orderId, returnCode);
            if (isFirst) {
                ygUserBalanceService.incomeRecharge(userId, new BigDecimal(10), OperationType.FreightSubsidy, orderId.toString(), "女王退货补偿运费", "sys");
            }
        }
    }

    @Override
    public Boolean isFirstReturnInStockByOrder(Long orderId, String returnCode) {
        List<YgReturnOrderLog> logs = ygReturnOrderLogService.findReturnLogByOrderId(orderId);
        Boolean isFirst = true;
        if (!CollectionUtils.isEmpty(logs)) {
            Map<String, List<YgReturnOrderLog>> collect = logs.stream().collect(Collectors.groupingBy(YgReturnOrderLog::getReturnCode));
            for (Entry<String, List<YgReturnOrderLog>> entry : collect.entrySet()) {
                if (returnCode.equals(entry.getKey())) {
                    continue;
                }
                List<YgReturnOrderLog> logList = entry.getValue();
                List<ReturnStatus> rsList = logList.parallelStream().map(log -> log.getReturnStatus()).collect(Collectors.toList());

                if (rsList.contains(ReturnStatus.WaitingInStock)) {
                    if (rsList.contains(ReturnStatus.WaitingSend)) {
                        // 售后换
                        isFirst = false;

                    } else if (rsList.contains(ReturnStatus.WaitingReturnMoney)) {
                        // 售后退
                        isFirst = false;
                    }

                }
            }

        }
        return isFirst;

    }

    public int updateReturnStatusByCode(YgReturnOrder order) {
        Assert.notNull(order.getReturnCode());
        YgReturnOrderExample example = new YgReturnOrderExample();
        example.createCriteria().andStatusEqualTo(DataStatus.Valid.name()).andReturnCodeEqualTo(order.getReturnCode()).andReturnStatusNotEqualTo(order
                .getReturnStatus().name());

        return ygReturnOrderMapper.updateByExampleSelective(order, example);

    }

    @Override
    public List<YgReturnOrder> findOrderForComplete(Date limitDate) {
        return ygReturnOrderMapper.selectOrderForComplete(limitDate);
    }

    @Override
    public int returnOrderForCompleteTask(List<String> returnCodes) {

        return ygReturnOrderMapper.returnOrderForCompleteTask(returnCodes);
    }

    @Override
    public List<OrderReturnInfo> findReOrder4Cancel(Date limitDate) {
        return ygReturnOrderMapper.selectReOrder4Cancel(limitDate);
    }

    @Override
    public int updateReOrderForCancel(List<String> returnCodes) {
        return ygReturnOrderMapper.updateReOrderForCancel(returnCodes);
    }

    @Override
    public List<Map<String, Object>> getReturnOrderReport(Date startDate, Date endDate, String returnType, String productName) {
        return ygReturnOrderMapper.selectReturnOrderReport(startDate, endDate, returnType, productName);

    }

    @Override
    public List<YgReturnOrder> findByOrderId(Long orderId, ReturnType returnType, ReturnMode returnMode, ReturnStatus... returnStatus) {
        YgReturnOrderExample example = new YgReturnOrderExample();
        YgReturnOrderExample.Criteria criteria = example.createCriteria().andOrderIdEqualTo(orderId).andStatusEqualTo(DataStatus.Valid.name());
        if (returnType != null) {
            criteria.andReturnTypeEqualTo(returnType.name());
        }
        if (returnStatus != null && returnStatus.length > 0) {
            List<String> collect = Arrays.asList(returnStatus).stream().map(r -> r.name()).collect(Collectors.toList());
            criteria.andReturnStatusIn(collect);
        }
        if (returnMode != null) {
            criteria.andReturnModeEqualTo(returnMode.name());
        }
        List<YgReturnOrder> list = ygReturnOrderMapper.selectByExample(example);
        return list;
    }

    @Override
    public YgReturnOrder findReturnOrderMoneryById(Long id) {

        YgReturnOrder returnOrder = ygReturnOrderMapper.selectReturnOrderMoneryById(id);
        return returnOrder;
    }

    @Override
    public Message alipayRefundSuccess(String batchNo, String success_num, String resultDetails) {
        int i = ygAlipayRefundRecordService.updateSuccess(batchNo, new Date(), resultDetails);
        YgAlipayRefundRecord refundRecord = ygAlipayRefundRecordService.findByBatchNo(batchNo);
        this.doRefund(refundRecord.getReturnId(), refundRecord.getRefundReason(), refundRecord.getCreateBy(), refundRecord.getRefundAccountPrice(),
                refundRecord.getRefundPrice(), Constant.YIIGOO_PLATFORM_NO);
        return Message.success(i);
    }

    @Override
    public Message autoAuditReturnOrder(String returnCode, String handler, String remark, Boolean pass) {
        YgReturnOrder ygReturnOrder = this.findDetailByReCode(returnCode);

        YgOrder ygOrder = ygOrderService.findOrderDetailByOrderId(ygReturnOrder.getOrderId());
        Boolean autoAudit = true;
        String str = "";
        OrderStatus orderStatus = OrderStatus.WaitingSend;
        if (ReturnReasonType.ReturnDifference.equals(ygReturnOrder.getReturnReasonType())) {
            str = ReturnReasonType.ReturnDifference.getTitle();
        } else {
            for (YgReturnOrderDetail rod : ygReturnOrder.getReturnOrderDetails()) {
                for (YgOrderDetail od : ygOrder.getOrderDetail()) {
                    if (rod.getSourceSkuCode().equals(od.getSkuCode())) {

                        if (od.getDetailStatus().equals(OrderDetailStatus.WaitingSign) || od.getDetailStatus().equals(OrderDetailStatus.Audited)) {
                            str += od.getProductName() + "已发货;";
                            orderStatus = OrderStatus.WaitingSign;
                            autoAudit = false;
                        } else {
                            str += od.getProductName() + "未发货;";
                        }
                    }
                    if (rod.getSupplierId().equals(trustonerSupplierId)) {
                        autoAudit = false;
                    }
                }
            }
        }
        ygReturnLogService.addReturnLog(returnCode, ygReturnOrder.getOrderId(), "自动审核" + autoAudit, "autoAuditReturnOrder", str);
        if (autoAudit) {
            return this.auditReturnOrder(returnCode, remark, ygOrder.getUserId(), handler, pass, orderStatus);
        }
        return Message.error("部分商品已审核或发货，不予自动审核", str);

    }

    @Override
    public List<CheckReturnModel> existReturn(Long orderId, List<Long> sourceSkuIds) {
        return ygReturnOrderMapper.existReturn(orderId, sourceSkuIds);
    }

    @Override
    public Message checkReturn(Long orderId, List<Long> sourceSkuIds, ReturnType returnType) {
        YgOrder order = ygOrderService.findByOrderId(orderId);
        if (order.getSendTime() != null && order.getSendTime().before(DateConvertUtils.addDay(new Date(), -10))) {
            return Message.error("发货已超过十天，不予退换", null);
        }
        Boolean returnAble = true;
        Map<String, Object> map = this.existenceReturnByOrderId(orderId);
        if (ReturnType.Change.equals(returnType)) {
            returnAble = (Boolean) map.get("changeAble");
        } else {
            returnAble = (Boolean) map.get("returnAble");
        }
        if (!returnAble) {
            return Message.error("每个订单只允许" + returnType + "一次", null);
        }
        List<CheckReturnModel> list = this.existReturn(orderId, sourceSkuIds);
        if (!CollectionUtils.isEmpty(list)) {
            return Message.error("部分商品存在多次退换货", null);
        }
        return Message.success(null);
    }

    @Override
    public YgReturnOrder findOtherReturn(Long orderId, String returnCode) {
        YgReturnOrderExample example = new YgReturnOrderExample();
        String[] returnStatus = new String[]{ReturnStatus.Cancel.name(), ReturnStatus.Reject.name()};
        example.createCriteria().andOrderIdEqualTo(orderId).andReturnCodeNotEqualTo(returnCode).andReturnStatusNotIn(Arrays.asList(returnStatus))
                .andStatusEqualTo(DataStatus.Valid.name());
        List<YgReturnOrder> list = ygReturnOrderMapper.selectByExample(example);
        if (!CollectionUtils.isEmpty(list)) {
            return list.get(0);
        }
        return null;
    }

    @Override
    public Message closeOrderByReturn(Long orderId, ReturnMode returnMode, String returnCode) {
        Boolean allReturn = this.isAllReturn(orderId);
        List<Long> skuIds = null;
        if (allReturn) {
            YgOrder order = ygOrderService.findByOrderId(orderId);
            if (OrderStatus.WaitingCheck.equals(order.getOrderStatus()) || OrderStatus.WaitingSend.equals(order.getOrderStatus())) {
                ygOrderService.closeOrderBySystem(orderId, "全部退货");
                order.setOrderStatus(OrderStatus.TradeClosed);
            }
        } else {
            List<YgReturnOrderDetail> returnDetails = ygReturnOrderDetailService.findByReturnCode(returnCode);
            skuIds = returnDetails.stream().map(YgReturnOrderDetail::getSourceSkuId).collect(Collectors.toList());

        }
        ygOrderDetailService.updateRefundStatusByReturn(orderId, RefundStatus.RefundSuccess, skuIds);

        return Message.success("");
    }

    @Autowired
    private WdtQybPushOrderByDetailApi wdtQybPushOrderByDetailApi;

    private void pushWdtByRefundMonery(String returnCode, Long orderId) {
        new Thread(() -> {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            List<YgReturnOrderDetail> returnOrderDetailList = ygReturnOrderDetailService.findByReturnCode(returnCode);
            List<YgOrderDetail> orderDetailList = ygOrderDetailService.findByOrderId(orderId);
            Set<String> outCodes = new HashSet<>();
            for (YgReturnOrderDetail returnOrderDetail : returnOrderDetailList) {
                for (YgOrderDetail orderDetail : orderDetailList) {
                    if (StringUtil.isBlank(orderDetail.getOutCode())) {
                        continue;
                    }
                    if (orderDetail.getId().equals(returnOrderDetail.getOdId())
                            || orderDetail.getSkuId().equals(returnOrderDetail.getSourceSkuId())) {
                        outCodes.add(orderDetail.getOutCode());
                    }
                }
            }
            outCodes.forEach(outCode -> {
                wdtQybPushOrderByDetailApi.pushOrderToWdtByOutCode(outCode, null);
            });
        }).start();


    }

    @Override
    public BigDecimal residualRefundPrice(Long orderId) {
        return ygReturnOrderMapper.residualRefundPrice(orderId);
    }

    @Override
    public BigDecimal residualRefundPriceOnlyPaid(Long orderId) {
        return ygReturnOrderMapper.residualRefundPriceOnlyPaid(orderId);
    }

    @Override
    public Boolean isAllReturn(Long orderId) {
        List<ResidualRefundSku> list = this.residualRefundSku(orderId);
        if (!CollectionUtils.isEmpty(list)) {
            Long reduce = list.stream().map(ResidualRefundSku::getResidualAmount).reduce(0L, (s1, s2) -> s1 + s2);
            if (reduce <= 0L) {
                return true;
            }
        }
        return false;
    }

    @Override
    public List<ResidualRefundSku> residualRefundSku(Long orderId) {

        return ygReturnOrderMapper.residualRefundSku(orderId);
    }

    @Override
    public List<YgReturnOrder> findByReturnStatusHasDetail(Date startDate, Date endDate, String returnCode, ReturnType returnType, ReturnStatus...
            returnStatus) {
        return this.findByReturnStatusHasDetail(startDate, endDate, returnCode, returnType, null, returnStatus);
    }

    @Override
    public List<YgReturnOrder> findByReturnStatusHasDetail(Date startDate, Date endDate, String returnCode, ReturnType returnType, Long supplierId,
                                                           ReturnStatus... returnStatus) {
        return ygReturnOrderMapper.selectByReturnStatusHasDetail(startDate, endDate, returnCode, returnType,
                supplierId, null, null,
                returnStatus == null || returnStatus.length == 0 ? null : returnStatus);
    }

    @Override
    public List<YgReturnOrder> findByReturnStatusHasDetail(Date startDate, Date endDate, String returnCode,
                                                           ReturnType returnType, Long supplierId, Boolean afterSales,
                                                           ReturnReasonType returnReasonType, ReturnStatus... returnStatus) {
        return ygReturnOrderMapper.selectByReturnStatusHasDetail(startDate, endDate, returnCode, returnType, supplierId,
                afterSales, returnReasonType == null ? null : returnReasonType.name(),
                returnStatus == null || returnStatus.length == 0 ? null : returnStatus);
    }

    @Override
    public List<String> findExistsReturnCode(List<String> returnCodeList) {
        return ygReturnOrderMapper.selectExistsReturnCode(returnCodeList);
    }

    @Override
    public int saveReturnOrderList(List<YgReturnOrder> returnOrderList) {
        return new AbstractSplitListTemplate<YgReturnOrder>(returnOrderList) {
            @Override
            public int execute(List<YgReturnOrder> recordList) {
                return insertBatch(recordList);
            }
        }.split();
    }

    @Override
    public int updateWdtOrderCode(List<String> returnCodeList) {
        if (CollectionUtils.isEmpty(returnCodeList)) {
            return 0;
        }
        return ygReturnOrderMapper.updateWdtOrderCode(returnCodeList);
    }

    @Override
    public int updateReturnStatusByReturnCode(List<YgReturnOrder> updateOrderList) {
        if (CollectionUtils.isEmpty(updateOrderList)) {
            return 0;
        }
        return ygReturnOrderMapper.updateReturnStatusByReturnCode(updateOrderList);
    }

    @Override
    public List<YgReturnOrder> findChangeDetailBySendTime(Date startDate, Date endDate, Long supplierId, Boolean afterSales) {
        return ygReturnOrderMapper.selectChangeDetailBySendTime(startDate, endDate, supplierId, afterSales);
    }

    @Override
    public List<Map<String, Object>> findReturnedInfoBySupplier(Date startDate, Date endDate, Long supplierId, Boolean afterSales) {
        return ygReturnOrderMapper.selectReturnedInfoBySupplier(startDate, endDate, supplierId, afterSales);
    }

    private int insertBatch(List<YgReturnOrder> returnOrderList) {
        int row = ygReturnOrderMapper.insertBatch(returnOrderList);
        if (row > 0) {
            List<YgReturnOrderDetail> returnOrderDetailList = new ArrayList<>();
            returnOrderList.forEach(returnOrder -> returnOrderDetailList.addAll(returnOrder.getReturnOrderDetails()));
            ygReturnOrderDetailService.saveBatch(returnOrderDetailList);
        }
        return row;
    }

    @Override
    public Boolean isExitNotCompleteReturn(Long orderId, ReturnType returnType, ReturnMode returnMode) {

        ReturnStatus[] returnStatus = new ReturnStatus[]{ReturnStatus.WaitingCheck, ReturnStatus.WaitingReturnGoods, ReturnStatus.WaitingInStock,
                ReturnStatus.WaitingSign, ReturnStatus.WaitingReturnMoney, ReturnStatus.WaitingSend};
        List<YgReturnOrder> list = this.findByOrderId(orderId, returnType, returnMode, returnStatus);
        if (CollectionUtils.isEmpty(list)) {
            return false;
        }
        return true;
    }

    @Override
    public ResultSet<YgReturnOrder> searchReturnForAgent(QueryInfo queryInfo, Long supplierId, ReturnType returnType, String returnCode, Date startDate, Date
            endDate, Long orderId, ReturnStatus returnStatus, String expressCode, String productName) {
        List<YgReturnOrder> list = ygReturnOrderMapper.selectReturnBySupplierId(queryInfo, supplierId, returnType, returnCode, startDate, endDate, orderId,
                returnStatus, expressCode, productName);

        int count = ygReturnOrderMapper.countReturnBySupplierId(supplierId, returnType, returnCode, startDate, endDate, orderId, returnStatus, expressCode,
                productName);
        ResultSet<YgReturnOrder> resultSet = new ResultSet<>(count, list);
        return resultSet;
    }

    @Override
    public List<Map<String, Object>> selectSendOrderBySupplier(Long supplierId, Date startDate, Date endDate) {
        return ygReturnOrderMapper.selectSendOrderBySupplier(supplierId, startDate, endDate);

    }

    @Override
    public List<Map<String, Object>> selectReturnBySupplier(Long supplierId, Date startDate, Date endDate) {

        return ygReturnOrderMapper.selectReturnBySupplier(supplierId, startDate, endDate);
    }

    @Override
    public List<Long> findOrderIdsByReturn(Date startDate, Date endDate, ReturnType returnType, ReturnStatus... returnStatus) {
        return ygReturnOrderMapper.selectOrderIdsByReturn(startDate, endDate, returnType, returnStatus);
    }

    @Override
    public int transferReturnOrder(Long sourceUserId, Long targetUserId) {
        YgReturnOrderExample example = new YgReturnOrderExample();
        example.createCriteria().andUserIdEqualTo(sourceUserId);
        YgReturnOrder record = new YgReturnOrder();
        record.setUserId(targetUserId);
        return ygReturnOrderMapper.updateByExampleSelective(record, example);
    }

    @Override
    public List<YgReturnOrder> findByOrderIdList(List<Long> orderIdList, ReturnType returnType) {
        if (CollectionUtils.isEmpty(orderIdList)) {
            return new ArrayList<>();
        }
        YgReturnOrderExample example = new YgReturnOrderExample();
        YgReturnOrderExample.Criteria criteria = example.createCriteria();
        if (returnType != null) {
            criteria.andReturnTypeEqualTo(returnType.name());
        }
        criteria.andOrderIdIn(orderIdList).andStatusEqualTo(DataStatus.Valid.name());
        return ygReturnOrderMapper.selectByExample(example);
    }

    @Override
    public Boolean isExist(String returnCode, ReturnType returnType) {
        YgReturnOrderExample example = new YgReturnOrderExample();
        YgReturnOrderExample.Criteria criteria = example.createCriteria();
        criteria.andReturnCodeEqualTo(returnCode).andReturnTypeEqualTo(returnType.name()).andStatusEqualTo(DataStatus.Valid.name());
        int i = ygReturnOrderMapper.countByExample(example);
        return i > 0;
    }

    @Override
    public int updateChangeSend(List<YgReturnOrder> changeList) {
        if (org.apache.commons.collections4.CollectionUtils.isEmpty(changeList)) {
            return 0;
        }
        return ygReturnOrderMapper.updateChangeSend(changeList);
    }

    /**
     * 卡券订单线下退款
     * 注：只支持未发货订单。
     *
     * @param orderId
     */
    private void doRefundByCardCouponOrder(Long orderId) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                YgOrder order = ygOrderService.findOrderDetailByOrderId(orderId);
                if (!OrderType.CardCoupon.equals(order.getOrderType())) {
                    return;
                }
                List<YgOrder> subList = ygOrderService.findByParentId(orderId); // 获取所有有效子单（包含删除状态订单并过滤主单本身）
                if (CollectionUtils.isEmpty(subList)) {
                    return;
                }
                List<Long> orderIdList = subList.stream().map(o -> o.getOrderId()).collect(Collectors.toList());
                ygOrderService.cancelOrderByTask(orderIdList, "卡券订单主单退款"); // 修改子单属性
                for (YgOrder subOrder : subList) {
                    ygOrderDetailService.updateRefundStatusByReturn(subOrder.getId(), RefundStatus.RefundSuccess, null); // 修改明细单属性
                    subOrder.setOrderStatus(OrderStatus.TradeClosed);
                    List<YgOrderDetail> orderDetail = ygOrderDetailService.findByOrderId(subOrder.getOrderId());
                    subOrder.setOrderDetail(orderDetail);
                }
                orderIdList.add(orderId);
                ygCardCouponDetailService.deleteByRelationId(orderIdList);// 所有相关卡券失效
                try {
                    wdtQybApi.tradePushBatch(subList); // 旺店通取消订单
                } catch (WdtException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    @Override
    public List<YgReturnOrder> findDetailByReturnCodeList(List<String> returnCodeList) {
        if (CollectionUtils.isEmpty(returnCodeList)) {
            return null;
        }
        return ygReturnOrderMapper.selectDetailByReturnCodeList(returnCodeList);
    }
}
